<!-- eslint-disable no-undef -->
<script setup>
import { ref, watch, onMounted, onUnmounted } from 'vue'
import { useWindowSize, useThrottleFn } from '@vueuse/core'
import VideoSrc from '@/assets/video.mp4'
import { useMouse } from '@/hooks/mouse.js'
import { useBroad } from '@/hooks/broad.js'
import StatsInfo from './component/StatsInfo.vue'
import ActionMenu from './component/ActionMenu.vue'
import CreatePeer from './component/CreatePeer.vue'
const cursorLock = ref(false)
const actionRef = ref(null)
const peerRef = ref(null)
const isConn = ref(false)
const videoStream = ref(null)
const isStream = ref(false)
const cursorRef = ref(null)
const { offsetX, offsetY, addMouseEvent, removeMouseEvent } = useMouse()
const { addBroadEvent, removeBroadEvent } = useBroad()
const { width, height } = useWindowSize()
const statsDetail = ref({ frameWidth: 0 })
let statsTask = null
const rtcConfiguration = {
  iceServers: [
    {
      urls: 'stun:119.97.143.86:3478'
    },
    {
      urls: ['turn:119.97.143.86:3478'],
      credential: '1234',
      username: 'admin'
    }
  ]
  // "iceTransportPolicy": "relay"
}

/**
 * 监听鼠标的移动
 */
watch([offsetX, offsetY], () => {
  if (cursorLock.value) {
    cursorRef.value.style.left = offsetX.value + 'px'
    cursorRef.value.style.top = offsetY.value + 'px'
  }
})

// 监听收到视频流的尺寸
watch(
  () => statsDetail.value.frameWidth,
  (n, o) => {
    if (!o && n > 0) {
      console.log('初始化设置video...')
      setVideoSize()
    }
  }
)

// 监听屏幕尺寸的变化
const throttleSize = useThrottleFn(() => {
  setVideoSize()
}, 100)
watch([width, height], () => {
  throttleSize()
})

onMounted(() => {
  clearInterval(statsTask)
})
onUnmounted(() => {
  clearInterval(statsTask)
})

/**
 * 初始化p2p连接
 */
const signaling = new SignalingChannel()
const p2p = new Owt.P2P.P2PClient(
  {
    audioEncodings: true,
    videoEncodings: [
      {
        codec: {
          name: 'h264'
        }
      },
      {
        codec: {
          name: 'vp9'
        }
      },
      {
        codec: {
          name: 'vp8'
        }
      }
    ],
    rtcConfiguration
  },
  signaling
)

/**
 * 添加键盘鼠标监听事件
 */
watch(
  () => isStream.value,
  (val) => {
    if (val) {
      // 添加监听事件
      console.log('添加键鼠事件...')
      addMouseEvent(videoStream.value, p2p, peerRef.value.remoteId)
      addBroadEvent(p2p, peerRef.value.remoteId)
    } else {
      // 添加监听事件
      console.log('移除键鼠事件...')
      removeMouseEvent()
      removeBroadEvent()
    }
  }
)

/**
 * 测试视频显示操作
 */
const createVideo = () => {
  isStream.value = true
  document.body.style.cursor = 'none'
  videoStream.value.src = VideoSrc
  // addMouseEvent(document.body)
}

/**
 * 创建p2p链接
 */
const createP2PConnection = async (tag = true) => {
  if (!tag) {
    createVideo()
    return
  }
  try {
    await p2p.connect({
      host: peerRef.value.serverAddress,
      token: peerRef.value.localId
    })
    isConn.value = true
    setRemoteIds()
    console.log('连接成功...')
  } catch (err) {
    console.log(err)
  }
}

/**
 * 设置远端id
 */
const setRemoteIds = () => {
  p2p.allowedRemoteIds = [peerRef.value.remoteId]
}

/**
 * p2p监听流
 */
p2p.addEventListener('streamadded', (e) => {
  // 监听流是否断开
  e.stream.addEventListener('ended', () => {
    clearInterval(statsTask)
    console.log('Stream is removed...')
  })
  // 判断是否收到流
  isStream.value = true
  if (e.stream.source.audio || e.stream.source.video) {
    videoStream.value.srcObject = e.stream.mediaStream
  }
  // 监听推流信息
  statsTask = setInterval(() => {
    getStreamStat()
  }, 1000)
})
const setMuted = () => {
  videoStream.value.muted = !videoStream.value.muted
}

/**
 * 获取推流信息
 */
const getStreamStat = async () => {
  const statsResult = await p2p.getStats(peerRef.value.remoteId)
  statsResult.forEach((stats) => {
    if (stats.type === 'inbound-rtp' && stats.kind === 'video') {
      statsDetail.value = stats
    }
  })
}

/**
 * 设置菜单项的属性
 */
const changeAction = (obj) => {
  if (obj.type === 'size') {
    setVideoSize()
  }
}

/**
 * 设置视频自适应尺寸, 如果时全屏状态则不处理
 */
const setVideoSize = () => {
  if (actionRef.value.isAuto === 'auto') {
    console.log(width.value, height.value)
    if (statsDetail.value.frameWidth > statsDetail.value.frameHeight) {
      // 横屏-自适应比例
      if (statsDetail.value.frameWidth > width.value) {
        let _width = width.value
        let _height = (width.value / statsDetail.value.frameWidth) * statsDetail.value.frameHeight
        if (_height > height.value) {
          _height = height.value
          _width = (height.value / statsDetail.value.frameHeight) * statsDetail.value.frameWidth
        }
        videoStream.value.style.height = _height + 'px'
        videoStream.value.style.width = _width + 'px'
      } else {
        videoStream.value.style.width = width.value + 'px'
        videoStream.value.style.height = height.value + 'px'
      }
    } else {
      // 竖屏-自适应比例
      if (statsDetail.value.frameHeight > height.value) {
        videoStream.value.style.width =
          (height.value / statsDetail.value.frameHeight) * statsDetail.value.frameWidth + 'px'
        videoStream.value.style.height = height.value + 'px'
      } else {
        videoStream.value.style.width = width.value + 'px'
        videoStream.value.style.height = height.value + 'px'
      }
    }
  } else {
    videoStream.value.style.width = '100vw'
    videoStream.value.style.height = '100vh'
  }
}
</script>
<template>
  <div class="peer-stream">
    <!--webrtc统计信息-->
    <stats-info v-if="isStream" :stats-detail="statsDetail"></stats-info>
    <!--配置菜单信息-->
    <action-menu
      ref="actionRef"
      :stats-detail="statsDetail"
      @changeAction="changeAction"
      :is-stream="isStream"
    ></action-menu>
    <!--创建连接-->
    <create-peer
      v-show="!isStream"
      :is-conn="isConn"
      ref="peerRef"
      @createPeer="createP2PConnection(true)"
    ></create-peer>
    <!--游戏画面渲染-->
    <video
      @click="setMuted"
      v-show="isStream"
      ref="videoStream"
      class="video-stream"
      muted
      autoplay
    ></video>
    <!--鼠标指针-->
    <div
      v-if="false"
      ref="cursorRef"
      class="cursor-bg w-[32px] h-[32px] absolute z-10 top-0 left-0"
    ></div>
  </div>
</template>
<style scoped lang="scss">
.peer-stream {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-color: #333;
  .cursor-bg {
    background: url('')
      0% 0% / 100% 100%;
    pointer-events: none;
  }
  .video-stream {
    position: fixed;
    z-index: 9;
    width: 0px;
    height: 0px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    object-fit: fill;
  }
}
</style>
